home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
hard
/
drivr
/
BetaScan_1.12.lha
/
BetaScan
/
ScannerDev
/
packer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-10-04
|
3KB
|
125 lines
/*----------------------------------------------------------------------*
* packer.c Convert data to "cmpByteRun1" run compression. 11/15/85
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* control bytes:
* [0..127] : followed by n+1 bytes of data.
* [-1..-127] : followed by byte to be repeated (-n)+1 times.
* -128 : NOOP.
*
* This version for the Commodore-Amiga computer.
*----------------------------------------------------------------------*/
#include <exec/types.h>
#include "packer.h"
#define DUMP 0
#define RUN 1
#define MinRun 3
#define MaxRun 128
#define MaxDat 128
static LONG putSize;
#define GetByte() (*source++)
#define PutByte(c) { *dest++ = (c); ++putSize; }
static char buf[256]; /* [TBD] should be 128? on stack?*/
static BYTE *PutDump( BYTE *dest,int nn)
{
int i;
PutByte(nn-1);
for( i = 0 ; i < nn ; i++)
PutByte(buf[i]);
return(dest);
}
static BYTE *PutRun(BYTE *dest,int nn,int cc)
{
PutByte(-(nn-1));
PutByte(cc);
return(dest);
}
#define OutDump(nn) dest = PutDump(dest, nn)
#define OutRun(nn,cc) dest = PutRun(dest, nn, cc)
/*----------- PackRow --------------------------------------------------*/
/* Given POINTERS TO POINTERS, packs one row, updating the source and
destination pointers. RETURNs count of packed bytes.*/
ULONG PackRow(BYTE* source,BYTE* dest,ULONG rowSize)
{
char c,lastc = '\0';
BOOL mode = DUMP;
short nbuf = 0; /* number of chars in buffer */
short rstart = 0; /* buffer index current run starts */
putSize = 0;
buf[0] = lastc = c = GetByte(); /* so have valid lastc */
nbuf = 1;
rowSize--; /* since one byte eaten.*/
for( ; rowSize ; --rowSize )
{
buf[nbuf++] = c = GetByte();
switch( mode )
{
case DUMP:
/* If the buffer is full, write the length byte then the data */
if( nbuf>MaxDat )
{
OutDump(nbuf-1);
buf[0] = c;
nbuf = 1;
rstart = 0;
break;
}
if( c == lastc )
{
if( nbuf-rstart >= MinRun )
{
if( rstart > 0 )
OutDump(rstart);
mode = RUN;
}
else if( rstart == 0 )
mode = RUN; /* no dump in progress, so can't lose by making these 2 a run.*/
}
else
rstart = nbuf-1; /* first of run */
break;
case RUN:
if( (c != lastc) || (nbuf-rstart > MaxRun) )
{
/* output run */
OutRun(nbuf-1-rstart,lastc);
buf[0] = c;
nbuf = 1; rstart = 0;
mode = DUMP;
}
break;
}
lastc = c;
}
switch( mode )
{
case DUMP:
OutDump(nbuf);
break;
case RUN:
OutRun(nbuf-rstart,lastc);
break;
}
if( putSize & 0x01 )
PutByte(-128);
return (ULONG)putSize;
}